package animator.phantom.renderer.plugin;

/*
    Copyright Janne Liljeblad

    This file is part of Phantom2D.

    Phantom2D is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Phantom2D is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Phantom2D.  If not, see <http://www.gnu.org/licenses/>.
*/

import animator.phantom.plugin.*;
import animator.phantom.renderer.*;
import animator.phantom.renderer.param.*;
import animator.phantom.paramedit.*;
import animator.phantom.gui.view.*;
import animator.phantom.gui.view.editlayer.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import java.awt.image.*;
import giotto2D.core.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.util.*;

public class GeomObject3DPlugin extends Phantom3DPlugin
{
	private static int BOX = 0;
	private static int CONE = 1;
	private static int SPHERE = 2;
	private static int CYLINDER = 3;

	private static int FLOW_IMAGE = 0;
	private static int COLOR_APP = 1;

	private IntegerParam objectType;
	private IntegerParam textType;
	private ColorParam color;
	private BooleanParam normalsIn;
	private IntegerParam divisions;

	public GeomObject3DPlugin()
	{
		init3DPlugin();
	}

	public void buildDataModel()
	{
		setName( "3D Geometric Object" );

		objectType = new IntegerParam( 0 );
		textType = new IntegerParam( 0 );
		color = new ColorParam( new Color( 128, 128, 128 ) );
		normalsIn = new BooleanParam( false );
		divisions = new IntegerParam( 20, 3, 300 );

		register3DCoords();
		registerParameter( textType );
		registerParameter( color );
		registerParameter( normalsIn );
		registerParameter( divisions );
	}

	public void buildEditPanel()
	{

		String[] objOptions = {"Box", "Cone", "Sphere", "Cylinder" };
		IntegerComboBox objEdit = new IntegerComboBox( objectType, "Object",  objOptions );
		String[] ttOptions = {"Flow image", "Color" };
		IntegerComboBox ttEdit = new IntegerComboBox( textType, "Object texture",  ttOptions );
		ParamColorSelect colorEdit = new ParamColorSelect( color, "Color" );
		BooleanComboBox normEdit = new BooleanComboBox( normalsIn, "Texture normals", "inwards", "outwards", false );
		IntegerNumberEditor divE = new IntegerNumberEditor( "Divisions", divisions );

		addEditor( objEdit );
		addRowSeparator();
		add3DCoordsEditors();
		addEditor( ttEdit );
		addRowSeparator();
		addEditor( colorEdit );
		addRowSeparator();
		addEditor( normEdit );
		addRowSeparator();
		addEditor( divE );
		addRowSeparator();

	}

	public void renderFullScreenMovingSource( float frameTime, Graphics2D g, int width, int height )
	{
		BufferedImage flowTexture = getFlowImage();
		Appearance objApp = null;
		boolean generateTextureCoords = true;
		if( flowTexture != null && textType.get() ==  FLOW_IMAGE )
			objApp = createTexturedAppearance( flowTexture );
		else
			objApp = getColorAppearance( color.get() );
			generateTextureCoords = false;

		//--- Render image
		AnimCoords3D coords = (AnimCoords3D) getCoords();
		Node shape = getShape( objApp, true, normalsIn.get(), divisions.get() );
		BufferedImage img = render3DImage( frameTime, coords, shape, PluginUtils.getScreenSize() );

		//--- render and combine alpha
		Appearance whiteApp = getWhiteAppearance();
 		Node shapeAlpha = getShape( whiteApp, false, false, divisions.get() );
		BufferedImage alpha3DImg = render3DImage( frameTime, coords, shapeAlpha, PluginUtils.getScreenSize() );
		combineAlpha( img, alpha3DImg );

		g.drawImage( img, 0, 0, null );
	}

	private Node getShape( Appearance app, boolean textureCoords, boolean normalsIn, int disivion )
	{
		int flag1 = textureCoords ? Primitive.GENERATE_TEXTURE_COORDS : 0;
		int flag2 = normalsIn ? Primitive.GENERATE_NORMALS_INWARD : 0;
		int primflags = Primitive.GEOMETRY_NOT_SHARED | flag1 | flag2;
		Node node = null;
		if( objectType.get() == BOX )
		{
			node = new Box( 1.0f,
					1.0f,
					1.0f,
					primflags,
					app );
		}
		if( objectType.get() == CONE )
		{
			node = new Cone(	1.0f,
						2.0f,
						primflags,
						disivion,
						disivion,
						app );
		}
		if( objectType.get() == SPHERE )
		{
			node = new Sphere( 1.0f, primflags, disivion, app ); 
		}
		if( objectType.get() == CYLINDER )
		{
			node = new Cylinder(	1.0f, 
						2.0f,
						primflags,
						disivion, 
						disivion,
						app ); 
		}

		return node;
	}

}//end class
